package ink.metoo.gude.module.security.service.impl

import ink.metoo.gude.module.security.domain.JwtConst
import ink.metoo.gude.module.security.domain.ddl.User
import ink.metoo.gude.properties.JwtProperties
import ink.metoo.gude.module.security.util.JwtTokenMapper
import ink.metoo.gude.module.security.service.TokenService
import ink.metoo.gude.util.logger
import io.jsonwebtoken.Claims
import org.springframework.stereotype.Service

@Service
class JwtTokenServiceImpl(private val jwtProperties: JwtProperties) : TokenService {

    private val log = logger()
    private val jwtTokenMapper: JwtTokenMapper = JwtTokenMapper(jwtProperties)

    override fun createToken(user: User): String = jwtTokenMapper.createToken(user)

    override fun getClaims(token: String): Claims? = try {
        jwtTokenMapper.getClaims(token)
    } catch (e: Exception) {
        log.debug("token is invalid", e)
        null
    }

    override fun isTokenExpired(claims: Claims, user: User): Boolean {
        val userPasswordLastModifiedDate = user.passwordLastModifiedDate
        if (userPasswordLastModifiedDate != null) {
            val passwordLastModifiedDate = claims[JwtConst.PASSWORD_VALID_VERIFICATION_NAME]
            if (passwordLastModifiedDate !is Long) {
                return true
            }
            if (passwordLastModifiedDate != userPasswordLastModifiedDate.time) {
                return true
            }
        }
        return jwtTokenMapper.isTokenExpired(claims)
    }

    override fun jwtProperties(): JwtProperties = jwtProperties

}